#include<event2/event.h>
#include<event2/listener.h>
#include<iostream>
#include<string.h>
#include <signal.h>
#include<event2/bufferevent.h>
#include <event2/buffer.h>
#define SPORT 6666
using namespace std;
bufferevent_filter_result filter_in(evbuffer *s,evbuffer *d,ev_ssize_t limit,bufferevent_flush_mode mode, void *arg)
{
    cout<<"filter_in"<<endl;
    //读取并清理源数据
    char data[1024]={0};
    int len=evbuffer_remove(s,data,sizeof(data)-1);
    //把所有字母转成大写
    for(int i=0;i<len;i++)
    {
        data[i]=toupper(data[i]);
    }
    evbuffer_add(d,data,len);
    return BEV_OK;
}
bufferevent_filter_result filter_out(evbuffer *s,evbuffer *d,ev_ssize_t limit,bufferevent_flush_mode mode, void *arg)
{
    char data[1024]={0};
    int len=evbuffer_remove(s,data,sizeof(data)-1);
    string str="";
    str+="==================\n";
    str+=data;
    str+="==================\n";
    evbuffer_add(d,str.c_str(),str.size());
    return BEV_OK;
}
void read_cb(bufferevent *bev,void *arg)
{
    cout<<"read_cb"<<endl;
    char data[1024]={0};
    int len=bufferevent_read(bev,data,sizeof(data)-1);
    cout<<data<<endl;
    //回复消息
    bufferevent_write(bev,data,len);
}
void write_cb(bufferevent *bev,void *arg)
{
    
}
void event_cb(bufferevent *bev,short events,void *arg)
{

}
void listen_cb(struct evconnlistener * e, evutil_socket_t s, struct sockaddr * a, int socklen, void *arg)
{
    cout<<"listen_cb"<<endl;
    //创建bufferevent 绑定bufferevent_filter
    event_base *base=(event_base*)arg;
    bufferevent *bev=bufferevent_socket_new(base,s,BEV_OPT_CLOSE_ON_FREE);
    bufferevent *bev_filter=bufferevent_filter_new(bev,
        filter_in,//输入过滤函数
        filter_out,//输出过滤函数
        BEV_OPT_CLOSE_ON_FREE,
        0,//清理的回调函数
        0//传递给回调的参数
    );
    //设置bufferevent的回调
    bufferevent_setcb(bev_filter,read_cb,write_cb,event_cb,nullptr);
    bufferevent_enable(bev_filter,EV_READ|EV_WRITE);
}
int main()
{
    //忽略管道信号，发生数据给已关闭的sokect
    if(signal(SIGPIPE,SIG_IGN)==SIG_ERR)
    {
        return 1;
    }
    //创建libevent上下文
    event_base *base =event_base_new();
    if(base)
    {
        cout<<"event_base successful"<<endl;
    }
    //监听端口：sokect listen bind 绑定事件
    sockaddr_in sin;
    memset(&sin,0,sizeof(sin));
    sin.sin_family=AF_INET;
    sin.sin_port=htons(SPORT);
    evconnlistener *evlisten= evconnlistener_new_bind(base,//libevent 上下文
        listen_cb,//接受到连接的回调函数
        base,//回调函数获取的参数arg
        LEV_OPT_REUSEABLE | LEV_OPT_CLOSE_ON_FREE,//地址重用，listen关闭sokect
        10,//连接管理队列大小，对应listen函数
        (sockaddr*)&sin, //绑定地址和端口
        sizeof(sin)
    );
    //事件分发处理
    event_base_dispatch(base);
    //清理
    evconnlistener_free(evlisten);
    if(base)
        event_base_free(base);
    return 0;
}